package com.hmall.common.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

/**
 * 日期时间工具类
 * 提供常用的日期时间格式化、解析和计算功能
 */
public class DateTimeUtil {
    
    // 常用日期时间格式
    public static final String PATTERN_DEFAULT = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_DATE = "yyyy-MM-dd";
    public static final String PATTERN_TIME = "HH:mm:ss";
    public static final String PATTERN_COMPACT = "yyyyMMddHHmmss";
    public static final String PATTERN_CHINESE = "yyyy年MM月dd日 HH时mm分ss秒";
    
    private DateTimeUtil() {
        // 私有构造方法，防止工具类被实例化
    }
    
    /**
     * 获取当前日期时间字符串（默认格式）
     */
    public static String now() {
        return format(LocalDateTime.now());
    }
    
    /**
     * 格式化日期时间（默认格式）
     */
    public static String format(LocalDateTime dateTime) {
        return format(dateTime, PATTERN_DEFAULT);
    }
    
    /**
     * 格式化日期时间（指定格式）
     */
    public static String format(LocalDateTime dateTime, String pattern) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * 格式化日期
     */
    public static String formatDate(LocalDate date) {
        return formatDate(date, PATTERN_DATE);
    }
    
    /**
     * 格式化日期（指定格式）
     */
    public static String formatDate(LocalDate date, String pattern) {
        if (date == null) {
            return null;
        }
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * 解析日期时间字符串（默认格式）
     */
    public static LocalDateTime parse(String dateTimeStr) {
        return parse(dateTimeStr, PATTERN_DEFAULT);
    }
    
    /**
     * 解析日期时间字符串（指定格式）
     */
    public static LocalDateTime parse(String dateTimeStr, String pattern) {
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * 解析日期字符串
     */
    public static LocalDate parseDate(String dateStr) {
        return parseDate(dateStr, PATTERN_DATE);
    }
    
    /**
     * 解析日期字符串（指定格式）
     */
    public static LocalDate parseDate(String dateStr, String pattern) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * 将Date转换为LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }
    
    /**
     * 将LocalDateTime转换为Date
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }
    
    /**
     * 获取指定日期的开始时间（00:00:00）
     */
    public static LocalDateTime startOfDay(LocalDate date) {
        return date.atStartOfDay();
    }
    
    /**
     * 获取指定日期的结束时间（23:59:59）
     */
    public static LocalDateTime endOfDay(LocalDate date) {
        return date.atTime(LocalTime.MAX);
    }
    
    /**
     * 获取指定月份的第一天
     */
    public static LocalDate firstDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.firstDayOfMonth());
    }
    
    /**
     * 获取指定月份的最后一天
     */
    public static LocalDate lastDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.lastDayOfMonth());
    }
    
    /**
     * 计算两个日期之间的天数差
     */
    public static long daysBetween(LocalDate startDate, LocalDate endDate) {
        return Math.abs(Period.between(startDate, endDate).getDays());
    }
    
    /**
     * 计算两个日期时间之间的秒数差
     */
    public static long secondsBetween(LocalDateTime start, LocalDateTime end) {
        return Math.abs(Duration.between(start, end).getSeconds());
    }
    
    /**
     * 日期时间加法（增加天数）
     */
    public static LocalDateTime plusDays(LocalDateTime dateTime, long days) {
        return dateTime.plusDays(days);
    }
    
    /**
     * 日期时间减法（减少天数）
     */
    public static LocalDateTime minusDays(LocalDateTime dateTime, long days) {
        return dateTime.minusDays(days);
    }
    
    /**
     * 判断日期是否在指定范围内
     */
    public static boolean isBetween(LocalDate date, LocalDate start, LocalDate end) {
        return !date.isBefore(start) && !date.isAfter(end);
    }
    
    /**
     * 判断日期时间是否在指定范围内
     */
    public static boolean isBetween(LocalDateTime dateTime, LocalDateTime start, LocalDateTime end) {
        return !dateTime.isBefore(start) && !dateTime.isAfter(end);
    }
    
    /**
     * 获取时间戳（毫秒）
     */
    public static long getTimestamp() {
        return System.currentTimeMillis();
    }
    
    /**
     * 获取指定日期时间的时间戳
     */
    public static long getTimestamp(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
}